package com.zqxq.common.utils;

import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.Vector;


public class TimeZoneUtils {

    public static final String GMT="GMT";
    private static String DATE_FORMAT ="yyyy-MM-dd HH:mm:ss";
    //两个时区转换
    public static String timeZoneConverter(Date sourceDate, TimeZone sourceTimeZone, TimeZone targetTimeZone, String dateFormat) {
        Long targetTime = sourceDate.getTime() - sourceTimeZone.getRawOffset() + targetTimeZone.getRawOffset();
        DateFormat formatter = new SimpleDateFormat(dateFormat);
        return formatter.format(new Date(targetTime));
    }

    //两个时区转换
    public static String timeZoneConverter(Date sourceDate, TimeZone targetTimeZone, String dateFormat) {
        TimeZone sourceTimeZone = TimeZone.getTimeZone("GMT");
        return timeZoneConverter(sourceDate, sourceTimeZone, targetTimeZone, dateFormat);
    }

    //两个时区转换
    public static String timeZoneConverter(Date sourceDate, TimeZone targetTimeZone) {
        return timeZoneConverter(sourceDate, targetTimeZone, DATE_FORMAT);
    }

    //两个时区转换
    public static String timeZoneConverter(Date sourceDate, String timeZone) {
        TimeZone targetTimeZone = TimeZone.getTimeZone(timeZone);
        return timeZoneConverter(sourceDate, targetTimeZone, DATE_FORMAT);
    }
    //两个时区转换
    public static String timeZoneConverter(String sourceDate, String timeZone) {
        String result = null;
        try {
            Date date = DateUtils.parseDate(sourceDate, DATE_FORMAT);
            result = timeZoneConverter(date, timeZone);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 将日期时间字符串根据转换为指定时区的日期时间
     * @param date
     * @param targetFormater
     * @param targetTimeZoneId
     * @return
     */
    public static String converter(Date date, String targetFormater, String targetTimeZoneId) {

        if (StringUtils.isEmpty(targetFormater)){
            throw new IllegalArgumentException("缺少参数 dstFormater");
        }
        if (StringUtils.isEmpty(targetTimeZoneId)){
            throw new IllegalArgumentException("缺少参数 targetTimeZoneId");
        }
        Date d = converter(date,targetTimeZoneId);
        return DateUtils.dateToStr(d,targetFormater);
    }

    /**
     *  时区转换
     * @param date
     * @param targetTimeZoneId
     * @return
     */
    public static Date converter(Date date,  String targetTimeZoneId) {
        int diffTime = getDiffTimeZoneRawOffset(targetTimeZoneId);
        long nowTime = date.getTime();
        long newNowTime = nowTime - diffTime;
        Date d = new Date(newNowTime);
        return d;
    }

    public static String converter(Date date) {
        String targetTimeZoneId=GMT;
        return converter(date,DateUtils.DATE_FORMAT_DATETIME,targetTimeZoneId);
    }
    /**
     * 获取系统当前默认时区与UTC的时间差.(单位:毫秒)
     *
     * @return 系统当前默认时区与UTC的时间差.(单位:毫秒)
     */
    private static int getDefaultTimeZoneRawOffset() {
        return TimeZone.getDefault().getRawOffset();
    }

    /**
     * 获取指定时区与UTC(GMT)的时间差.(单位:毫秒)
     * @param timeZoneId 时区Id
     * @return 指定时区与UTC的时间差.(单位:毫秒)
     */
    private static int getTimeZoneRawOffset(String timeZoneId) {
        return TimeZone.getTimeZone(timeZoneId).getRawOffset();
    }

    /**
     * 获取系统当前默认时区与指定时区的时间差.(单位:毫秒)
     *
     * @param timeZoneId 时区Id
     * @return 系统当前默认时区与指定时区的时间差.(单位:毫秒)
     */
    private static int getDiffTimeZoneRawOffset(String timeZoneId) {
        return TimeZone.getDefault().getRawOffset()- TimeZone.getTimeZone(timeZoneId).getRawOffset();
    }
    /**
     * 将日期时间字符串根据转换为指定时区的日期时间.
     *
     * @param srcFormater 待转化的日期时间的格式.
     * @param srcDateTime 待转化的日期时间.
     * @param targetFormater 目标的日期时间的格式.
     * @param targetTimeZoneId 目标的时区编号.
     * @return 转化后的日期时间.
     */
    public static String converter(String srcDateTime,String srcFormater
            , String targetFormater, String targetTimeZoneId) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(srcFormater);
            Date d = sdf.parse(srcDateTime);
            return converter(d,targetFormater,targetTimeZoneId);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将日期时间字符串根据转换为指定时区的日期时间.
     *
     * @param sourceDateTime 待转化的日期时间.
     * @param targetTimeZoneId 目标的时区编号.
     * @return 转化后的日期时间.
     * @see #converter(String, String, String, String)
     */
    public static String converterDefault(String sourceDateTime,
                                                String targetTimeZoneId) {
        return converter(sourceDateTime,DateUtils.DATE_FORMAT_DATETIME,
                DateUtils.DATE_FORMAT_DATETIME, targetTimeZoneId);
    }
    /**
     * 获取所有的时区编号. <br>
     * 排序规则:按照ASCII字符的正序进行排序. <br>
     * 排序时候忽略字符大小写.
     * @return 所有的时区编号(时区编号已经按照字符[忽略大小写]排序).
     */
    public static String[] fecthAllTimeZoneIds() {
        Vector v = new Vector();
        String[] ids = TimeZone.getAvailableIDs();
        for (int i = 0; i < ids.length; i++) {
            v.add(ids[i]);
        }
        java.util.Collections.sort(v, String.CASE_INSENSITIVE_ORDER);
        v.copyInto(ids);
        v = null;
        return ids;
    }

    public static void main(String[] args) {
        String[] strs = fecthAllTimeZoneIds();
        for (int i=0;i<strs.length;i++){
            System.out.println(strs[i] +"");
        }
    }
}
